# - * - coding: utf-8 - * -
import os
import librosa
import matplotlib
import numpy as np
import matplotlib.pyplot as plt
import sys
from PyQt5 import QtWidgets
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QLabel, QWidget
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
from matplotlib.lines import Line2D
from pydub import AudioSegment

matplotlib.use('Qt5Agg')  # 指定 Matplotlib 使用 PyQt5 后端
# plt.figure(dpi=600) # 将显示的所有图分辨率调高
matplotlib.rc("font",family='SimHei') # 显示中文
matplotlib.rcParams['axes.unicode_minus']=False # 显示符号


def get_audio_length_pydub(file_path):
    # 加载音频文件
    audio = AudioSegment.from_file(file_path)
    # 计算音频长度（毫秒）
    duration = len(audio)
    return duration


class MusicSlider(QWidget):
    filePath = ""
    samples = 44100

    vline1_pos = 0  # 初始位置
    vline2_pos = 1.0  # 初始位置
    timeLen = 0

    def __init__(self, filePath: str, samples=44100):
        super().__init__()

        self.filePath = filePath
        self.samples = samples
        self.timeLen = get_audio_length_pydub(self.filePath)
        print(self.timeLen)

        self.setFixedHeight(150)

        self.startTime = QLabel('')
        self.startTime.setMaximumWidth(150)
        self.startTime.setAlignment(Qt.AlignCenter)
        self.setStartTimeLabel()
        # 创建一个 Matplotlib Figure
        self.figure = Figure()
        self.figure.patch.set_alpha(0)
        self.figure.subplots_adjust(left=0, right=1, bottom=0, top=1)
        self.canvas = FigureCanvas(self.figure)
        self.set_mpl_fig()
        self.endTime = QLabel('')
        self.endTime.setMaximumWidth(150)
        self.endTime.setAlignment(Qt.AlignCenter)
        self.setEndTimeLabel()

        # 创建一个布局，并将画布添加到布局中
        layout = QtWidgets.QHBoxLayout()
        layout.addWidget(self.startTime)
        layout.addWidget(self.canvas)
        layout.addWidget(self.endTime)
        self.setLayout(layout)

        self.selected_line = None

    def setStartTimeLabel(self):
        sec = self.vline1_pos*self.timeLen/1000
        secLabel = "{:2.3f}".format(sec)
        self.startTime.setText(f'开始时间\n{secLabel}秒')

    def setEndTimeLabel(self):
        sec = self.vline2_pos*self.timeLen/1000
        secLabel = "{:2.3f}".format(sec)
        self.endTime.setText(f'开始时间\n{secLabel}秒')

    def set_mpl_fig(self):
        # 创建一个子图并在其中绘制数据
        samples, sr = librosa.load(self.filePath, sr=self.samples)
        # samples = samples[6000:16000]
        print(samples)
        print(len(samples), sr)
        time = np.arange(0, len(samples)) * (1.0 / sr)
        print(time)
        ax = self.figure.add_subplot(111)
        # 设置子图背景为蓝色
        ax.set_facecolor('blue')

        ax.plot(time, samples, antialiased=True)

        # 移除边框和坐标轴
        ax.axis('off')

        # 添加两条可拖动辅助线
        self.vline1 = Line2D([self.vline1_pos, self.vline1_pos], [samples.min(), samples.max()], color='red', linestyle='--', lw=2, alpha=0.8)
        self.vline2 = Line2D([self.vline2_pos, self.vline2_pos], [samples.min(), samples.max()], color='green', linestyle='--', lw=2, alpha=0.8)
        print(samples.min())
        print(samples.max())
        ax.add_line(self.vline1)
        ax.add_line(self.vline2)

        # 存储初始辅助线位置


        # 添加鼠标事件回调
        self.canvas.mpl_connect('motion_notify_event', self.on_mouse_move)
        self.canvas.mpl_connect('button_press_event', self.on_mouse_press)
        # 绑定鼠标释放事件
        self.canvas.mpl_connect('button_release_event', self.on_mouse_release)

        self.canvas.draw()  # 更新画布以显示图表

    # 鼠标按下事件
    def on_mouse_press(self, event):
        # 检查是否点击了辅助线附近
        if event.inaxes:  # 鼠标仅在坐标轴范围内有效
            x = event.xdata
            if abs(x - self.vline1_pos) < 0.02:
                self.selected_line = 'vline1'
            elif abs(x - self.vline2_pos) < 0.02:
                self.selected_line = 'vline2'
            else:
                self.selected_line = None

    # 鼠标移动事件
    def on_mouse_move(self, event):
        if event.inaxes and self.selected_line:  # 鼠标在范围内
            x = event.xdata
            if self.selected_line == 'vline1':  # 拖动红色辅助线
                if x >= 0 and x < self.vline2_pos:
                    self.vline1.set_xdata([x, x])
                    self.vline1_pos = x
                    self.setStartTimeLabel()
            elif self.selected_line == 'vline2':  # 拖动绿色辅助线
                if x <= 1 and x > self.vline1_pos:
                    self.vline2.set_xdata([x, x])
                    self.vline2_pos = x
                    self.setEndTimeLabel()

            # 更新画布
            self.canvas.draw()

    def on_mouse_release(self, event):
        # 处理鼠标释放事件
        if event.inaxes and self.selected_line:  # 确保鼠标在子图范围内
            self.selected_line = None
            print(self.vline1_pos)
            print(self.vline2_pos)

class ApplicationWindow(QtWidgets.QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle('PyQt Matplotlib Example')

        # 创建一个布局，并将画布添加到布局中
        layout = QtWidgets.QHBoxLayout()

        musicSlider = MusicSlider(r'./convert/[LOL英雄配音 佐伊]我在这呢_爱给网_aigei_com.mp3', 44100)

        layout.addWidget(musicSlider)

        widget = QtWidgets.QWidget()
        widget.setLayout(layout)
        self.setCentralWidget(widget)




if __name__ == '__main__':
    # ffmpeg环境引入
    current_path = os.path.abspath(os.getcwd())
    # current_path.replace('/', '//')
    ffmpeg_path = current_path + "\\" + "ffmpeg-7.1-essentials_build\\bin"
    os.environ["PATH"] += os.pathsep + ffmpeg_path
    # print(os.environ["PATH"])

    app = QtWidgets.QApplication(sys.argv)
    main = ApplicationWindow()
    main.show()
    sys.exit(app.exec_())




# def displayWaveform(): # 显示语音时域波形
#     """
#     display waveform of a given speech sample
#     :param sample_name: speech sample name
#     :param fs: sample frequency
#     :return:
#     """
#     samples, sr = librosa.load(r'./convert/牛蛙的叫声_爱给网_aigei_com.wav', sr=44100)
#     # samples = samples[6000:16000]
#
#     print(len(samples), sr)
#     time = np.arange(0, len(samples)) * (1.0 / sr)
#
#     plt.plot(time, samples)
#     # plt.title("语音信号时域波形")
#     # plt.xlabel("时长（秒）")
#     # plt.ylabel("振幅")
#     # plt.savefig("./convert/1.jpg")
#     # 隐藏坐标轴
#     plt.axis('off')
#     plt.show()

